package cn.sciento.websocket.redis;

import cn.sciento.core.convertor.ApplicationContextHelper;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import cn.sciento.core.redis.RedisHelper;
import cn.sciento.websocket.config.WebSocketConfig;
import cn.sciento.websocket.vo.UserVO;
import org.springframework.context.ApplicationContext;

public class SessionUserRedis {
    private static RedisHelper redisHelper;

    private static RedisHelper getRedisHelper() {
        ApplicationContext applicationContext = ApplicationContextHelper.getContext();
        if (redisHelper == null) {
            redisHelper = applicationContext.getBean(RedisHelper.class);
        }
        redisHelper.setCurrentDatabase(applicationContext.getBean(WebSocketConfig.class).getRedisDb());
        return redisHelper;
    }

    private static void clear() {
        if (redisHelper == null) {
            redisHelper = ApplicationContextHelper.getContext().getBean(RedisHelper.class);
        }
        redisHelper.clearCurrentDatabase();
    }

    private static String getCacheKey() {
        return "websocket:session-users";
    }

    private static String getCacheKey(Long tenantId) {
        return "websocket:session-users:" + tenantId;
    }

    public static void refreshCache(UserVO user) {
        RedisHelper redisHelper = getRedisHelper();
        long date = System.nanoTime();
        redisHelper.zSetAdd(getCacheKey(), redisHelper.toJson(user), date);
        redisHelper.zSetAdd(getCacheKey(user.getTenantId()), redisHelper.toJson(user), date);
        clear();
    }

    public static void deleteCache(UserVO user) {
        RedisHelper redisHelper = getRedisHelper();
        redisHelper.zSetRemove(getCacheKey(), redisHelper.toJson(user));
        redisHelper.zSetRemove(getCacheKey(user.getTenantId()), redisHelper.toJson(user));
        clear();
    }

    public static void deleteCache(List<UserVO> userList) {
        RedisHelper redisHelper = getRedisHelper();
        userList.forEach(user -> redisHelper.zSetRemove(getCacheKey(), redisHelper.toJson(user)));
        userList.forEach(user -> redisHelper.zSetRemove(getCacheKey(user.getTenantId()), redisHelper.toJson(user)));
        clear();
    }

    public static Long getSize() {
        RedisHelper redis = getRedisHelper();
        Long total = redis.zSetSize(getCacheKey());
        clear();
        return total;
    }

    public static Long getSize(Long tenantId) {
        RedisHelper redis = getRedisHelper();
        Long total = redis.zSetSize(getCacheKey(tenantId));
        clear();
        return total;
    }

    public static List<UserVO> getCache(int page, int size) {
        RedisHelper redis = getRedisHelper();
        long start = (size * page);
        Long end = start + size - 1L;
        Set<String> keySets = redis.zSetRange(getCacheKey(), start, end);
        clear();
        List<UserVO> list = new ArrayList<>();
        keySets.forEach(item -> list.add(redis.fromJson(item, UserVO.class)));
        return list;
    }

    public static List<UserVO> getCache(int page, int size, long tenantId) {
        RedisHelper redis = getRedisHelper();
        long start = (size * page);
        Long end = start + size - 1L;
        Set<String> keySets = redis.zSetRange(getCacheKey(tenantId), start, end);
        clear();
        List<UserVO> list = new ArrayList<>();
        keySets.forEach(item -> list.add(redis.fromJson(item, UserVO.class)));
        return list;
    }

    public static List<UserVO> getCache() {
        RedisHelper redis = getRedisHelper();
        Long count = redis.zSetSize(getCacheKey());
        Set<String> keySets = redis.zSetRange(getCacheKey(), 0L, count);
        clear();
        List<UserVO> list = new ArrayList<>();
        keySets.forEach(item -> list.add(redis.fromJson(item, UserVO.class)));
        return list;
    }

    public static List<UserVO> getCache(Long tenantId) {
        RedisHelper redis = getRedisHelper();
        Long count = redis.zSetSize(getCacheKey(tenantId));
        Set<String> keySets = redis.zSetRange(getCacheKey(tenantId), 0L, count);
        clear();
        List<UserVO> list = new ArrayList<>();
        keySets.forEach(item -> list.add(redis.fromJson(item, UserVO.class)));
        return list;
    }
}
